/*
 * Copyright 2008-2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.faxsun.controller.account;

import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.validator.GenericValidator;
import org.broadleafcommerce.common.config.RuntimeEnvironmentPropertiesManager;
import org.broadleafcommerce.common.exception.ServiceException;
import org.broadleafcommerce.common.util.TransactionUtils;
import org.broadleafcommerce.core.order.domain.Order;
import org.broadleafcommerce.core.order.service.OrderService;
import org.broadleafcommerce.core.pricing.service.exception.PricingException;
import org.broadleafcommerce.core.web.controller.account.BroadleafUpdateAccountController;
import org.broadleafcommerce.core.web.controller.account.UpdateAccountForm;
import org.broadleafcommerce.profile.core.dao.RoleDao;
import org.broadleafcommerce.profile.core.domain.Customer;
import org.broadleafcommerce.profile.core.domain.CustomerAddress;
import org.broadleafcommerce.profile.core.service.CustomerAddressService;
import org.broadleafcommerce.profile.web.core.CustomerState;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.faxsun.controller.account.validator.UpdateMobileValidator;
import com.faxsun.controller.uc.entity.CHANNEL;
import com.faxsun.profile.core.domain.FSCustomerImpl;
import com.faxsun.profile.core.domain.FSReceiver;
import com.faxsun.profile.core.domain.FSThirdPartyCustomer;
import com.faxsun.profile.core.service.FSReceiverService;
import com.faxsun.profile.core.service.FSThirdPartyCustomerService;
import com.faxsun.validation.FSMergeAccontValidator;
import com.faxsun.web.pojos.WechatUserInfo;
import com.faxsun.web.utils.WechatApiUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

@Controller
@RequestMapping("/account")
public class UpdateAccountController extends BroadleafUpdateAccountController {

	@Resource(name = "blConfigurationManager")
	protected RuntimeEnvironmentPropertiesManager runtimeEnvironment;

	@Resource(name = "blMergeAccountValidator")
	protected FSMergeAccontValidator mergeAccountValidator;

	@Resource(name = "fsReceiverService")
	protected FSReceiverService blfsReceiverService;

	@Resource(name = "blCustomerAddressService")
	public CustomerAddressService blCustomerAddressService;

	@Resource(name = "blOrderService")
	public OrderService blOrderService;

	@Resource(name = "blRoleDao")
	protected RoleDao roleDao;

	@Resource(name = "fsUpdateMobileValidator")
	protected UpdateMobileValidator updateMobileValidator;

	@Resource(name = "blThirdPartyCustomerService")
	FSThirdPartyCustomerService fscustomer3thService;

	@Resource(name = "wechatApiUtils")
	protected WechatApiUtils wechatApiUtils;

	protected String accountUpdatedMessage = "成功更新账户信息";

	protected String accountMergedMessage = "成功合并账户信息";

	protected String mobileBindedMessage = "手机绑定成功";

	protected String mobileUnbinedMessage = "手机解绑成功";

	@RequestMapping(method = RequestMethod.GET)
	public String viewUpdateAccount(HttpServletRequest request, Model model,
			@ModelAttribute("updateAccountForm") UpdateAccountForm form,
			@ModelAttribute("updateMobileForm") FSUpdateMobileForm mobileForm,
			@ModelAttribute("mergeAccountForm") MergeAccountForm mergeAccountForm) {
		String ret = super.viewUpdateAccount(request, model, form);

		// 设置手机信息
		FSCustomerImpl customer = (FSCustomerImpl) CustomerState.getCustomer();
		String mobile = customer.getMobile();
		if (mobile == null || mobile.isEmpty()) {
			mobileForm.setMobile("");
			mobileForm.setType(0);
		} else {
			mobileForm.setMobile(mobile);
			mobileForm.setType(1);
		}
		// show user3th merge view
		model.addAttribute("isMerged", customer.isMerged());
		model.addAttribute("isU3th", customer.isCustomer3th());
		setThirdAccountInfo(model, customer);
		return ret;
	}

	@RequestMapping(method = RequestMethod.POST)
	public String processUpdateAccount(HttpServletRequest request, Model model,
			@ModelAttribute("updateAccountForm") UpdateAccountForm form, BindingResult result,
			@ModelAttribute("updateMobileForm") FSUpdateMobileForm mobileForm,
			@ModelAttribute("mergeAccountForm") MergeAccountForm mergeAccountForm,
			RedirectAttributes redirectAttributes) throws ServiceException {
		mobileForm.setMobile(mobileForm.getMobile());
		mobileForm.setType(mobileForm.getType());
		mobileForm.setCaptcha("");
		String ret = super.processUpdateAccount(request, model, form, result, redirectAttributes);

		setThirdAccountInfo(model);
		if (ret.equals(getUpdateAccountView())) {
			FSCustomerImpl customer = (FSCustomerImpl) CustomerState.getCustomer();
			model.addAttribute("isMerged", customer.isMerged());
			model.addAttribute("isU3th", customer.isCustomer3th());
		}
		return ret;
		// FSCustomerImpl customer = (FSCustomerImpl)
		// CustomerState.getCustomer();
		// String reslut = super.processUpdateAccount(request, model, form,
		// result,
		// redirectAttributes);
		// if(reslut.equals(getUpdateAccountView())){
		// model.addAttribute("isMerged", customer.isMerged() );
		// model.addAttribute("isU3th", customer.isCustomer3th());
		// }
		// return reslut;
	}

	@Override
	public String getAccountUpdatedMessage() {
		return accountUpdatedMessage;
	}

	@RequestMapping(method = RequestMethod.POST, value = "/updateMobile")
	public String processMobileVerification(HttpServletRequest request, Model model,
			@ModelAttribute("updateMobileForm") FSUpdateMobileForm form, BindingResult result,
			@ModelAttribute("updateAccountForm") UpdateAccountForm accountForm,
			@ModelAttribute("mergeAccountForm") MergeAccountForm mergeAccountForm,
			RedirectAttributes redirectAttributes) throws ServiceException {
		FSCustomerImpl customer = (FSCustomerImpl) CustomerState.getCustomer();
		accountForm.setEmailAddress(customer.getEmailAddress());
		accountForm.setFirstName(customer.getFirstName());
		accountForm.setLastName(customer.getLastName());
		// show user3th merge view
		model.addAttribute("isMerged", customer.isMerged());
		model.addAttribute("isU3th", customer.isCustomer3th());
		// check parameters
		updateMobileValidator.validate(form, result, request.getSession());
		if (result.hasErrors()) {
			return getUpdateAccountView();
		}

		String oldMobile = customer.getMobile();

		if (form.getType() == 1 && oldMobile.equals(form.getMobile())) {
			// 手机号相同，且类型为解除绑定
			customer.setMobile(null);
			customer.setVerified(false);
		} else if (form.getType() == 0 && (oldMobile == null || oldMobile.isEmpty())) {
			// 帐户未绑定，则进行绑定，手机号在validator中验证是否已被绑定
			customer.setMobile(form.getMobile());
			customer.setVerified(true);
		} else {
			// TODO: 添加错误提示信息
			return getUpdateAccountView();
		}

		customerService.saveCustomer(customer);

		if (form.getType() == 0) {
			redirectAttributes.addFlashAttribute("successMobileMessage", mobileBindedMessage);
			form.setType(1);
		} else if (form.getType() == 1) {
			redirectAttributes.addFlashAttribute("successMobileMessage", mobileUnbinedMessage);
			form.setType(0);
		}
		form.setMobile(customer.getMobile());
		form.setCaptcha("");

		accountForm.setEmailAddress(customer.getEmailAddress());
		accountForm.setFirstName(customer.getFirstName());
		accountForm.setLastName(customer.getLastName());

		return getAccountRedirectView();
	}

	@RequestMapping(value = "/merge", method = RequestMethod.POST)
	@Transactional(TransactionUtils.DEFAULT_TRANSACTION_MANAGER)
	public String processMergeAccount(HttpServletRequest request, Model model,
			@ModelAttribute("mergeAccountForm") MergeAccountForm mergeAccountForm, BindingResult result,
			@ModelAttribute("updateAccountForm") UpdateAccountForm form,
			@ModelAttribute("updateMobileForm") FSUpdateMobileForm mobileForm, RedirectAttributes redirectAttributes)
					throws ServiceException {
		mergeAccountValidator.validate(mergeAccountForm, result);
		FSCustomerImpl c = (FSCustomerImpl) CustomerState.getCustomer();
		form.setEmailAddress(c.getEmailAddress());
		form.setFirstName(c.getFirstName());
		mobileForm.setMobile(c.getMobile());
		String currentMobile = c.getMobile();
		mobileForm.setType((currentMobile == null || currentMobile.isEmpty()) ? 0 : 1);

		if (result.hasErrors()) {
			return getUpdateAccountView();
		}

		String email = mergeAccountForm.getEmailAddress();
		Customer customer = customerService.readCustomerByEmail(email);

		String username = customer.getUsername();
		String mobile = ((FSCustomerImpl) customer).getMobile();
		String pwd = customer.getPassword();

		FSCustomerImpl customer3th = (FSCustomerImpl) CustomerState.getCustomer();

		// modify customer idcard: 1
		List<FSReceiver> receivers = blfsReceiverService.readByCustomer(customer);
		if (receivers != null) {
			for (FSReceiver receiver : receivers) {
				receiver.setCustomer(customer3th); // blc_idcard
				blfsReceiverService.save(receiver);
			}
		}

		// modify customer addresses: 2
		List<CustomerAddress> addresses = blCustomerAddressService
				.readActiveCustomerAddressesByCustomerId(customer.getId());
		if (addresses != null) {
			for (CustomerAddress address : addresses) {
				address.setCustomer(customer3th);
				blCustomerAddressService.saveCustomerAddress(address);
			}
		}

		// modify customer orders: 3
		List<Order> orders = blOrderService.findOrdersForCustomer(customer);
		if (orders != null) {
			for (Order order : orders) {
				order.setCustomer(customer3th);
				try {
					blOrderService.save(order, false);
				} catch (PricingException e) {
					e.printStackTrace();
				}
			}
		}

		customer.setDeactivated(true);

		// clear role : 4
		roleDao.removeCustomerRolesByCustomerId(customer.getId());

		// modify (3th party customer list) of the customer to current
		// customer3th if there are.
		List<FSThirdPartyCustomer> fscustomer3th = fscustomer3thService.readThirdPartyCustomerForCustomer(customer);
		for (FSThirdPartyCustomer c3 : fscustomer3th) {
			c3.setCustomer(customer3th);
		}
		customerService.saveCustomer(customer);
		/**** 删除用户 方案 ***/
		customerService.deleteCustomer(customer);

		customer3th.setUsername(username);
		customer3th.setPassword(pwd);
		customer3th.setEmailAddress(email);
		customer3th.setMerged(true);

		if (isMobileNO(username) && (customer3th.getMobile() == null || customer3th.getMobile().isEmpty())) {
			customer3th.setMobile(username);
			customer3th.setVerified(true);
			mobileForm.setMobile(username);
			mobileForm.setCaptcha("");
			mobileForm.setType(customer3th.isVerified() ? 1 : 0);
		} else if (GenericValidator.isEmail(username) && (customer3th.getMobile() == null)) {
			if (mobile != null && mobile != "") {
				customer3th.setMobile(mobile);
				customer3th.setVerified(true);
				mobileForm.setMobile(mobile);
				mobileForm.setCaptcha("");
				mobileForm.setType(customer3th.isVerified() ? 1 : 0);
			}
		}

		customerService.saveCustomer(customer3th);

		redirectAttributes.addFlashAttribute("successMessage", getAccountMergedMessage());

		form.setEmailAddress(email);
		form.setFirstName(customer3th.getFirstName());

		return getAccountRedirectView();
	}

	private boolean isMobileNO(String mobiles) {
		String regex = "^(1[345678])\\d{9}$";
		return match(regex, mobiles);
	}

	private boolean match(String regex, String str) {
		Pattern pattern = Pattern.compile(regex);
		Matcher matcher = pattern.matcher(str);
		return matcher.matches();
	}

	public String getAccountMergedMessage() {
		return accountMergedMessage;
	}

	/**
	 * 设置第三方帐户绑定信息
	 * 
	 * @param model
	 * @param customer
	 */
	private void setThirdAccountInfo(Model model, FSCustomerImpl customer) {

		if (customer == null) {
			return;
		}
		boolean isWechatBind = false;
		List<FSThirdPartyCustomer> thirdAccounts = fscustomer3thService.readThirdPartyCustomerForCustomer(customer);
		for (FSThirdPartyCustomer thirdAccount : thirdAccounts) {
			if (thirdAccount.getChannelId().equals(CHANNEL.WEIXIN.toString())) {
				// 获取微信用户name和头像
				WechatUserInfo wechatUserInfo = wechatApiUtils.getUserInfo(thirdAccount.getUid());
				model.addAttribute("wechatAccount", wechatUserInfo);
				isWechatBind = true;
			}
		}

		model.addAttribute("isWechatBind", isWechatBind);
	}

	/**
	 * 设置第三方帐户信息
	 * 
	 * @param model
	 */
	private void setThirdAccountInfo(Model model) {
		FSCustomerImpl customer = (FSCustomerImpl) CustomerState.getCustomer();
		setThirdAccountInfo(model, customer);
	}
}
